package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.tbit.common.entity.pojo.vo.DateResult;
import com.tbit.common.entity.vo.MainLogAuditVo;
import com.tbit.uqbike.constant.WorkType;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.dto.WorkOrderLogQueryDTO;
import com.tbit.uqbike.object.pojo.statistics.ExportPowerLog;
import com.tbit.uqbike.object.pojo.statistics.PowerLogDetail;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.business.AccountConfigExtService;
import com.tbit.uqbike.service.business.AccountUserService;
import com.tbit.uqbike.service.business.PowerChangeLogService;
import com.tbit.uqbike.service.business.WorkOrderService;
import com.tbit.uqbike.webmanager.business.maintain_performance.service.PowerChangePerformanceService;
import com.tbit.uqbike.webmanager.dao.core.AccountUserDao;
import com.tbit.uqbike.webmanager.dao.core.PowerChangeMonitorConfigMapper;
import com.tbit.uqbike.webmanager.dao.log.PowerChangeLogDao;
import com.tbit.uqbike.webmanager.util.DateUtils;
import com.tbit.utils.DateTimeUtil;
import com.tbit.utils.NullUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: chen
 * @Description: 换电记录
 * @Date: 创建于 11:27 2020/3/12
 */
@Slf4j
@Service("powerChangeLogService")
public class PowerChangeLogServiceImpl implements PowerChangeLogService {
    @Autowired
    private PowerChangeLogDao powerChangeLogDao;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private AccountUserDao accountUserDao;
    @Autowired
    private PowerChangeMonitorConfigMapper monitorConfigMapper;
    @Autowired
    private PowerChangePerformanceService performanceService;
    @Autowired
    private AccountConfigExtService accountConfigExtService;
    @Autowired
    private WorkOrderService workOrderService;


    public static void main(String[] args) {
        List<DateResult> results = new LinkedList<>();
        DateResult dateResult = new DateResult();
        dateResult.setDate("2022-03-01");
        DateResult dateResult1 = new DateResult();
        dateResult1.setDate("2022-03-03");
        DateResult dateResult2 = new DateResult();
        dateResult2.setDate("2022-03-02");
        results.add(dateResult);
        results.add(dateResult1);
        results.add(dateResult2);

        results.stream().sorted(Comparator.comparing(DateResult::getDate)).collect(Collectors.toList()).forEach(item -> {
            System.out.println(item.getDate());
        });
    }

    @Override
    public List<List<DateResult>> statisticsByTime(Integer accountId, Integer accountUserId, Long startTime,
                                                   Long endTime, Integer machineType, List<Integer> validList) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("accountUserId", accountUserId);
        map.put("startTime", new Date(startTime));
        map.put("endTime", new Date(endTime));
        map.put("machineType", machineType);
        map.put("validList", validList);

        List<List<DateResult>> totalList = new ArrayList<>();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        //获取运营区的所有分区id
        List<Region> list = accountUserDao.getRegionId(accountId);
        /**获取传入时间每天的日期*/
        List<String> findTimeList = DateTimeUtil.findDaysStr(simpleDateFormat.format(new Date(startTime)), simpleDateFormat.format(new Date(endTime)));
        /**获取要查询的数据*/
        List<DateResult> results = powerChangeLogDao.statisticsByTime(map);
        /**获取查询数据的日期集合*/
        List<String> dateList = results.stream().map(DateResult::getDate).collect(Collectors.toList());
        /**得到传入时间和查询数据日期集合的差集*/
        List<String> reduce = findTimeList.stream().filter(item -> !dateList.contains(item)).collect(Collectors.toList());
        /**进行补0*/
        if (!NullUtils.isEmpty(reduce)) {
            for (String date : reduce) {
                DateResult dateResult = new DateResult();
                dateResult.setDate(date);
                dateResult.setTotal(0);
                results.add(dateResult);
            }
        }
        /**根据日期排序*/
        results = results.stream().sorted(Comparator.comparing(DateResult::getDate)).collect(Collectors.toList());

        totalList.add(results);

        //获取对应分区下的数据
        map.put("regionIds", list.stream().map(Region::getRegionId).collect(Collectors.toList()));
        List<DateResult> allDateResult = powerChangeLogDao.mapByTimeAndRegionId(map);
        Map<Integer, List<DateResult>> dateMap = new HashMap<>();
        for (DateResult dateResult : allDateResult) {
            if (Objects.nonNull(dateMap.get(dateResult.getRegionId()))){
                dateMap.get(dateResult.getRegionId()).add(dateResult);
            }else {
                List<DateResult> dateResults = new ArrayList<>();
                dateResults.add(dateResult);
                dateMap.put(dateResult.getRegionId(), dateResults);
            }
        }

        for (Region region : list) {
            results = CollectionUtil.isEmpty(dateMap.get(region.getRegionId())) ? new ArrayList<>() : dateMap.get(region.getRegionId());
            /**获取查询数据的日期集合*/
            List<String> regionList = results.stream().map(DateResult::getDate).collect(Collectors.toList());
            /**得到传入时间和查询数据日期集合的差集*/
            List<String> reduceRegion = findTimeList.stream().filter(item -> !regionList.contains(item)).collect(Collectors.toList());
            /**进行补0*/
            if (!NullUtils.isEmpty(reduce)) {
                for (String date : reduceRegion) {
                    DateResult dateResult = new DateResult();
                    dateResult.setDate(date);
                    dateResult.setTotal(0);
                    results.add(dateResult);
                }
            }
            for (DateResult result : results) {
                result.setRegionId(region.getRegionId());
                if (region.getRegionId().equals(result.getRegionId())) {
                    result.setRegionName(region.getRegionName());
                }
            }
            //根据时间排序
            List<DateResult> collect = results.stream().sorted(Comparator.comparing(DateResult::getDate)).collect(Collectors.toList());
            totalList.add(collect);
        }
        totalList.removeIf(NullUtils::isEmpty);
        return totalList;
    }

    @Override
    public List<PowerLogDetail> queryPage(WorkOrderLogQueryDTO requestDTO) {
        Integer accountId = requestDTO.getAccountId();
        List<PowerLogDetail> logs = powerChangeLogDao.queryPage(requestDTO);
        PowerChangeMonitorConfig monitorConfig = Optional.ofNullable(monitorConfigMapper.selectById(accountId))
                .orElseGet(() -> new PowerChangeMonitorConfig().putDefaultValue(accountId));
        Map<Integer, AccountUser> accountUserMap = Optional.ofNullable(accountUserService.getByType(accountId, false))
                .map(x -> x.stream().collect(Collectors.toMap(AccountUser::getAccountUserId, v -> v, (v1, v2) -> v1)))
                .orElse(Collections.emptyMap());
        /**将名称和电话号码补齐*/
        if (!NullUtils.isEmpty(logs)) {
            for (PowerLogDetail powerLog : logs) {
                /**运维人员信息*/
                AccountUser accountUser = accountUserMap.get(powerLog.getAccountUserId());
                if (accountUser != null) {
                    powerLog.setName(accountUser.getName());
                    powerLog.setPhone(accountUser.getPhone());
                }
                powerLog.setPowerRange(monitorConfig.matchPowerRange(powerLog.getOldSoc()));
            }
        }
        return logs;
    }

    @Override
    public Integer queryCount(WorkOrderLogQueryDTO requestDTO) {
        return powerChangeLogDao.queryCount(requestDTO);
    }

    @Override
    public List<PowerLogDetail> exportByTime(WorkOrderLogQueryDTO queryDTO) {
        Integer accountId = queryDTO.getAccountId();
        List<PowerLogDetail> logs = powerChangeLogDao.exportByTime(queryDTO);
        List<AccountUser> list = accountUserService.getByType(accountId, false);
        PowerChangeMonitorConfig monitorConfig = Optional.ofNullable(monitorConfigMapper.selectById(accountId))
                .orElseGet(() -> new PowerChangeMonitorConfig().putDefaultValue(accountId));
        if (CollectionUtils.isNotEmpty(list)) {
            /**填充运维人员数据*/
            for (AccountUser a : list) {
                for (PowerLogDetail e : logs) {
                    if (a.getAccountUserId().equals(e.getAccountUserId())) {
                        e.setName(a.getName());
                        e.setPhone(a.getPhone());
                    }
                    e.setPowerRange(monitorConfig.matchPowerRange(e.getOldSoc()));
                }
            }
        }
        return logs;
    }

    @Override
    public List<ExportPowerLog> getByType(Integer accountId, Integer accountUserId, Long startTime, Long endTime, Integer rowCount,
                                          Integer pageNO, List<Integer> regionIdList, Integer type, Integer machineType) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        params.put("accountUserId", accountUserId);
        params.put("startTime", new Date(startTime));
        params.put("endTime", new Date(endTime));
        params.put("pageNO", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        params.put("regionIds", regionIdList);
        params.put("machineType", machineType);
        List<ExportPowerLog> logs;
        List<ExportPowerLog> powerLogList = new LinkedList<>();
        if (type == 0) {
            /**根据人员类型查看*/
            logs = powerChangeLogDao.selectByType(params);
            List<AccountUser> list = accountUserService.getByType(accountId, false);
            Map<Integer, AccountUser> map = new HashMap<>();
            if (list != null && list.size() > 0) {
                for (AccountUser accountUser : list) {
                    map.put(accountUser.getAccountUserId(), accountUser);
                }
            }
            if (!NullUtils.isEmpty(logs)) {
                /**根据运维人员id分组*/
                logs.stream().filter(data -> data.getAccountUserId() != null).collect(Collectors.groupingBy(ExportPowerLog::getAccountUserId)).forEach((key, value) -> {
                    ExportPowerLog powerLog = new ExportPowerLog();
                    /**封装数据*/
                    for (ExportPowerLog exportPowerLog : value) {
                        powerLog.setAccountUserId(key);
                        AccountUser accountUser = map.get(exportPowerLog.getAccountUserId());
                        if (!NullUtils.isEmpty(accountUser)) {
                            if (key.equals(accountUser.getAccountUserId())) {
                                powerLog.setName(accountUser.getName());
                                powerLog.setPhone(accountUser.getPhone());
                            }
                        }
                        if (exportPowerLog.getIsValid() == WorkType.workOrder_UnValid) {
                            powerLog.setUnValid(exportPowerLog.getTotal());
                        }
                        if (exportPowerLog.getIsValid() == WorkType.workOrder_Valid) {
                            powerLog.setValid(exportPowerLog.getTotal());
                        }
                        if (exportPowerLog.getIsValid() == WorkType.workOrder_underReview) {
                            powerLog.setUnderReview(exportPowerLog.getTotal());
                        }
                    }
                    /**总数累加*/
                    powerLog.setTotal(powerLog.getValid() + powerLog.getUnValid() + powerLog.getUnderReview());
                    powerLogList.add(powerLog);
                });
                return powerLogList;
            }
        } else if (type == 1) {
            /**根据分区类型查看*/
            logs = powerChangeLogDao.selectByTypeAndRegionId(params);

            /**查询某个运营区下所有的分区id*/
            List<Region> regionList = accountUserDao.getRegionId(accountId);

            Map<Integer, Region> map = new HashMap<>();
            if (regionList != null && regionList.size() > 0) {
                for (Region region : regionList) {
                    map.put(region.getRegionId(), region);
                }
            }
            if (!NullUtils.isEmpty(logs)) {
                logs.stream().filter(data -> data.getRegionId() != null).collect(Collectors.groupingBy(ExportPowerLog::getRegionId)).forEach((key, value) -> {
                    ExportPowerLog powerLog = new ExportPowerLog();
                    for (ExportPowerLog exportPowerLog : value) {
                        powerLog.setRegionId(key);
                        Region region = map.get(powerLog.getRegionId());
                        if (!NullUtils.isEmpty(region)) {
                            if (key.equals(region.getRegionId())) {
                                powerLog.setRegionName(region.getRegionName());
                            }
                        }

                        if (exportPowerLog.getIsValid() == WorkType.workOrder_UnValid) {
                            powerLog.setUnValid(exportPowerLog.getTotal());
                        }
                        if (exportPowerLog.getIsValid() == WorkType.workOrder_Valid) {
                            powerLog.setValid(exportPowerLog.getTotal());
                        }
                        if (exportPowerLog.getIsValid() == WorkType.workOrder_underReview) {
                            powerLog.setUnderReview(exportPowerLog.getTotal());
                        }
                    }
                    powerLog.setTotal(powerLog.getValid() + powerLog.getUnValid() + powerLog.getUnderReview());
                    powerLogList.add(powerLog);
                });
                return powerLogList;
            }
        }
        return powerLogList;
    }

    @Override
    public void updateAudit(MainLogAuditVo vo, LoginInfo loginInfo) {
        PowerLogDetail powerLogDetailDb = powerChangeLogDao.getTimeById(String.valueOf(vo.getLogId()));
        if (powerLogDetailDb == null) {
            return;
        }
        // 要修改为无效，但当前已是无效，则返回
        if (Objects.equals(vo.getIsValid(), WorkType.workOrder_UnValid)
                && Objects.equals(powerLogDetailDb.getIsValid(), WorkType.workOrder_UnValid)) {
            return;
        }
        // 要修改为有效，但当前已是有效，并且不修改绩效值，则返回
        if (Objects.equals(vo.getIsValid(), WorkType.workOrder_Valid)
                && Objects.equals(powerLogDetailDb.getIsValid(), WorkType.workOrder_Valid)
                && vo.getPerformance() == null) {
            return;
        }
        // 状态有变化，则更新。这里判断是为了过滤同时有效状态并且带有绩效值，但没必要修改状态的情况
        if (!Objects.equals(powerLogDetailDb.getIsValid(), vo.getIsValid())) {
            Date nowTime = new Date();
            // 审核人信息
            powerLogDetailDb.setAuditName(loginInfo.getName());
            powerLogDetailDb.setRemark(vo.getRemark() + ";审核人:" + loginInfo.getName() + ";审核时间:" + DateUtils.DateToString(nowTime) + ";");
            WorkOrderVO workOrderVO = new WorkOrderVO();
            workOrderVO.setIsValid(vo.getIsValid());
            // 根据换电记录查询换电工单记录
            WorkOrderVO orderVO = workOrderService.getDataById(vo.getLogId());
            if (!NullUtils.isEmpty(orderVO)) {
                workOrderVO.setWorkOrderId(orderVO.getWorkOrderId());
                // 换电记录审核状态和换电工单审核状态一致
                workOrderService.amendAuditState(workOrderVO);
            }
            powerLogDetailDb.setIsValid(vo.getIsValid());
            powerLogDetailDb.setAuditorId(loginInfo.accountUserId);
            powerLogDetailDb.setAuditTime(nowTime);
            powerChangeLogDao.amendAuditState(powerLogDetailDb);
        }

        // 有效改无效：删除现有记录
        if (Objects.equals(vo.getIsValid(), WorkType.workOrder_UnValid)) {
            performanceService.removePerformance(powerLogDetailDb.getPowerChangeLogId());
        }

        // 无效改有效：插入0分记录
        if (Objects.equals(vo.getIsValid(), WorkType.workOrder_Valid)) {
            // 绩效开关是否开启，则不插入
            AccountConfigExt performanceSwitch = accountConfigExtService.getByAccountIdAndType(powerLogDetailDb.getAccountId(), "power_change_performance");
            if (performanceSwitch != null && !performanceSwitch.getParamValue().equals("0")) {
                // 这个判断一下是否同时修改绩效值，如果有绩效值，则生成（或修改：如果已有绩效记录）一条绩效记录，并设置绩效值为当前传入的绩效值
                // 如果没有传绩效值，则是根据绩效配置生成绩效记录
                performanceService.generatePerformance(powerLogDetailDb, vo.getPerformance(), performanceSwitch);
            }
        }
    }
}
